import axios from "axios";
import { AxiosInstance } from "axios";
import { ElLoading } from "element-plus";
import { LoadingInstance } from "element-plus/es/components/loading/src/loading";
import { ylInterceptor, ylRequestConfig } from "./type";

const LOADING_DEFAULT = false;

class YLRequest {
  instance: AxiosInstance;
  interceptors?: ylInterceptor;

  isLoading: boolean;
  loading?: LoadingInstance;

  constructor(config: ylRequestConfig) {
    this.instance = axios.create(config);
    this.interceptors = config.interceptors;
    this.isLoading = config.isLoading ?? LOADING_DEFAULT;
    this.instance.interceptors?.request.use(
      this.interceptors?.requestInterceptor as any,
      this.interceptors?.requestInterceptorCatch
    );

    this.instance.interceptors?.response.use(this.interceptors?.responseInterceptor, this.interceptors?.responseInterceptorCatch);

    this.instance.interceptors.request.use(
      config => {
        if (this.isLoading) {
          this.loading = ElLoading.service({
            lock: true,
            text: "正在加载...",
            background: "rgba(0,0,0,.5)"
          });
        }
        return config;
      },
      err => {
        return err;
      }
    );
    this.instance.interceptors.response.use(
      res => {
        setTimeout(() => {
          this.loading?.close();
        }, 1000);
        return res.data;
      },
      err => {
        setTimeout(() => {
          this.loading?.close();
        }, 1000);
        return err;
      }
    );
  }

  request<T = any>(config: ylRequestConfig<T>): Promise<T> {
    return new Promise((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then(res => {
          resolve(res);
        })
        .catch(err => {
          reject(err);
        });
    });
  }
  get<T = any>(config: ylRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "GET" });
  }
  post<T = any>(config: ylRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "POST" });
  }
  delete<T = any>(config: ylRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "DELETE" });
  }
  patch<T = any>(config: ylRequestConfig<T>): Promise<T> {
    return this.request<T>({ ...config, method: "PATCH" });
  }
}

export default YLRequest;
